/*
 * AllocTemplate.h
 *
 *  Created on: 2011-3-26
 *      Author: wangchao
 */

#ifndef ALLOCTEMPLATE_H_
#define ALLOCTEMPLATE_H_
#include <e32cmn.h>
#include <e32base.h>

template< typename T >
int type_id( )
{
    static int _id = 0;
    return ( int )&_id;
}

template< typename type >
class Any
{
public:
    Any( type* p ) :
        _p( p ), _id( type_id< type > ( ) )
    {
        
    }
private:
    type* _p;
    int _id;
};

template< typename Class >
class Constructor0
{
public:
    static Class* NewL( )
    {
        Class* self = Constructor0::NewLC( );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( );
        return self;
    }
};

template< typename Class, typename Arg1 >
class Constructor1
{
public:
    static Class* NewL( Arg1 arg1 )
    {
        Class* self = Constructor1::NewLC( arg1 );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( Arg1 arg1 )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( arg1 );
        return self;
    }
};
template< typename Class, typename Arg1, typename Arg2 >
class Constructor2
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2 )
    {
        Class* self = Constructor2::NewLC( arg1, arg2 );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( Arg1 arg1, Arg2 arg2 )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( arg1, arg2 );
        return self;
    }
};

template< typename Class, typename Arg1, typename Arg2, typename Arg3 >
class Constructor3
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
        Class* self = Constructor3::NewLC( arg1, arg2, arg3 );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( arg1, arg2, arg3 );
        
        return self;
    }
};

/*
 template< typename Class, typename Arg1 = id, typename Arg2 = id >
 class Constructor< Class, Arg1, Arg2, id >
 {
 public:
 static Class* NewL( Arg1 arg1, Arg2 arg2 )
 {
 Class* self = Class::NewLC( arg1, arg2 );
 CleanupStack::Pop( self );
 return self;
 }
 
 static Class* NewLC( Arg1 arg1, Arg2 arg2 )
 {
 Class* self = new ( ELeave ) Class( );
 CleanupStack::PushL( self );
 self->ConstructL( arg1, arg2 );
 return self;
 }
 };

 template< typename Class, typename Arg1 = id >
 class Constructor< Class, Arg1, id, id >
 {
 public:
 static Class* NewL( Arg1 arg1 )
 {
 Class* self = Class::NewLC( arg1 );
 CleanupStack::Pop( self );
 return self;
 }
 
 static Class* NewLC( Arg1 arg1 )
 {
 Class* self = new ( ELeave ) Class( );
 CleanupStack::PushL( self );
 self->ConstructL( arg1 );
 return self;
 }
 };

 template< typename Class >
 class Constructor< Class, id, id, id >
 {
 public:
 static Class* NewL( )
 {
 Class* self = Class::NewLC( );
 CleanupStack::Pop( self );
 return self;
 }
 
 static Class* NewLC( )
 {
 Class* self = new ( ELeave ) Class( );
 CleanupStack::PushL( self );
 self->ConstructL( );
 return self;
 }
 };
 */
template< typename Class >
class AllocNoConstructL0
{
public:
    static Class* NewL( )
    {
        Class* self = new ( ELeave ) Class( );
        return self;
    }
};

template< typename Class, typename Arg1 >
class AllocNoConstructL1
{
public:
    static Class* NewL( Arg1 arg1 )
    {
        Class* self = new ( ELeave ) Class( arg1 );
        return self;
    }
};

template< typename Class, typename Arg1, typename Arg2 >
class AllocNoConstructL2
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2 )
    {
        Class* self = new ( ELeave ) Class( arg1, arg2 );
        return self;
    }
};

template< typename Class, typename Arg1, typename Arg2, typename Arg3 >
class AllocNoConstructL3
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
        Class* self = new ( ELeave ) Class( arg1, arg2, arg3 );
        return self;
    }
};

template< typename Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4 >
class AllocNoConstructL4
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
    {
        Class* self = new ( ELeave ) Class( arg1, arg2, arg3, arg4 );
        return self;
    }
};

template< typename Class >
class AllocWidthConstructL
{
public:
    static Class* NewL( )
    {
        Class* self = Class::NewLC( );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( );
        return self;
    }
};

template< typename Class, typename Arg1 >
class AllocWidthConstructL1
{
public:
    static Class* NewL( Arg1 arg1 )
    {
        Class* self = Class::NewLC( arg1 );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( Arg1 arg1 )
    {
        Class* self = new ( ELeave ) Class( arg1 );
        CleanupStack::PushL( self );
        self->ConstructL( );
        return self;
    }
};

template< typename Class, typename Arg1, typename Arg2, typename Arg3 >
class AllocWidthConstructL3
{
public:
    static Class* NewL( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
        Class* self = Class::NewLC( arg1, arg2, arg3 );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
        Class* self = new ( ELeave ) Class( arg1, arg2, arg3 );
        CleanupStack::PushL( self );
        self->ConstructL( );
        return self;
    }
};

class fWidget;
template< typename Class >
class AllocWindowWithConstructL
{
public:
    static Class* NewL( fWidget* engine )
    {
        Class* self = Class::NewLC( engine );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( fWidget* engine )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( engine );
        return self;
    }
};

template< typename Class, typename Arg >
class AllocWindowWithConstructL1
{
public:
    static Class* NewL( fWidget* engine, Arg arg )
    {
        Class* self = Class::NewLC( engine, arg );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( fWidget* engine, Arg arg )
    {
        Class* self = new ( ELeave ) Class( arg );
        CleanupStack::PushL( self );
        self->ConstructL( engine );
        return self;
    }
};
template< typename Class, typename Arg >
class AllocWindowWithConstructL2
{
public:
    static Class* NewL( fWidget* engine, Arg arg )
    {
        Class* self = Class::NewLC( engine, arg );
        CleanupStack::Pop( self );
        return self;
    }
    
    static Class* NewLC( fWidget* engine, Arg arg )
    {
        Class* self = new ( ELeave ) Class( );
        CleanupStack::PushL( self );
        self->ConstructL( engine, arg );
        return self;
    }
};
#endif /* ALLOCTEMPLATE_H_ */
